Webã¢ããªã±ãŒã·ã§ã³åãã®å ç¢ãªããã³ããšã³ãå ±æã¿ãŒã²ããããã»ããµãæ§ç¯ããããã®å æ¬çãªã¬ã€ããããŒã¿ç®¡çãã»ãã¥ãªãã£ãå ±æã³ã³ãã³ããåŠçããããã®ãã¹ããã©ã¯ãã£ã¹ãã«ããŒããŸãã
ããã³ããšã³ã Web Share Target Processor: ã·ã§ã¢ããŒã¿ç®¡çã®ãã¹ã¿ãŒ
Web Share Target APIã¯ãããã°ã¬ãã·ããŠã§ãã¢ããªïŒPWAïŒããã³ãŠã§ãã¢ããªã±ãŒã·ã§ã³ã«ãšããµã€ãã£ã³ã°ãªå¯èœæ§ãããããããŠãŒã¶ãŒãä»ã®ã¢ããªããã³ã³ãã³ããã·ãŒã ã¬ã¹ã«ããªãã®ã¢ããªã±ãŒã·ã§ã³ã«å ±æã§ããããã«ãªããŸãããã®æ©èœã¯ãŠãŒã¶ãŒãšã³ã²ãŒãžã¡ã³ããé«ããããã¹ã ãŒãºã§çµ±åããããšã¯ã¹ããªãšã³ã¹ãæäŸããŸããããããããã³ããšã³ãã§å ±æããŒã¿ã广çã«åŠçããã«ã¯ãæ éãªèšç»ãå ç¢ãªãšã©ãŒåŠçãããã³ã»ãã¥ãªãã£ãžã®æ³šåãäžå¯æ¬ ã§ãããã®å æ¬çãªã¬ã€ãã§ã¯ã匷åã§å®å šãªããã³ããšã³ãå ±æã¿ãŒã²ããããã»ããµãæ§ç¯ããããã»ã¹ã解説ããŸãã
Web Share Target APIã®çè§£
å®è£ ã«é²ãåã«ãWeb Share Target APIãç°¡åã«åŸ©ç¿ããŸããããããã¯åºæ¬çã«ããŠã§ãã¢ããªã±ãŒã·ã§ã³ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«å ±æã¿ãŒã²ãããšããŠèªèº«ãç»é²ã§ããããã«ããŸãããŠãŒã¶ãŒãå¥ã®ã¢ããªã±ãŒã·ã§ã³ããã³ã³ãã³ãïŒããã¹ããURLããã¡ã€ã«ãªã©ïŒãå ±æããããšãããšãããªãã®PWAãå ±æã·ãŒãã®ãªãã·ã§ã³ãšããŠè¡šç€ºãããŸãã
å
±æã¿ãŒã²ãããæå¹ã«ããã«ã¯ããŠã§ãã¢ããªã®ãããã§ã¹ãïŒmanifest.jsonïŒå
ã§å®çŸ©ããå¿
èŠããããŸãããã®ãããã§ã¹ãã¯ããã©ãŠã¶ãåä¿¡ããå
±æãªã¯ãšã¹ããã©ã®ããã«åŠçãããããã©ãŠã¶ã«äŒããŸãã以äžã«åºæ¬çãªäŸã瀺ããŸãã
{
"name": "My Awesome App",
"short_name": "Awesome App",
"start_url": "/",
"display": "standalone",
"background_color": "#fff",
"theme_color": "#000",
"icons": [
{
"src": "icon.png",
"sizes": "512x512",
"type": "image/png"
}
],
"share_target": {
"action": "/share-target",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"title": "title",
"text": "text",
"url": "url",
"files": [
{
"name": "sharedFiles",
"accept": ["image/*", "video/*"]
}
]
}
}
}
äž»èŠãªèŠçŽ ãåè§£ããŸãããã
action: å ±æããŒã¿ãåŠçããPWAå ã®URLããŠãŒã¶ãŒãã¢ããªã«ã³ã³ãã³ããå ±æãããšããã®URLãåŒã³åºãããŸããmethod: ããŒã¿ãéä¿¡ããããã«äœ¿çšãããHTTPã¡ãœãããå ±æã¿ãŒã²ããã«ã¯éåžžPOSTã䜿çšããŸããenctype: ããŒã¿ã®ãšã³ã³ãŒãã£ã³ã°ã¿ã€ããmultipart/form-dataã¯éåžžããã¡ã€ã«ãåŠçããã®ã«é©ããŠããŸãããapplication/x-www-form-urlencodedã¯ãããåçŽãªããã¹ãããŒã¹ã®ããŒã¿ã«äœ¿çšã§ããŸããparams: å ±æããŒã¿ããã©ãŒã ãã£ãŒã«ãã«ã©ã®ããã«ãããã³ã°ãããããå®çŸ©ããŸããããã«ãããå ±æãããŠããã¿ã€ãã«ãããã¹ããURLããã¡ã€ã«ã«ç°¡åã«ã¢ã¯ã»ã¹ã§ããŸãã
ãŠãŒã¶ãŒãå
±æã·ãŒãããããªãã®ã¢ããªãéžæãããšããã©ãŠã¶ã¯action URLã«ç§»åããå
±æããŒã¿ãPOSTãªã¯ãšã¹ããšããŠéä¿¡ããŸãã
ããã³ããšã³ãå ±æã¿ãŒã²ããããã»ããµã®æ§ç¯
å
±æã¿ãŒã²ããããã»ããµã®ã³ã¢ã¯ãæå®ãããaction URLã§åä¿¡ããããŒã¿ãåŠçããJavaScriptã³ãŒãã«ãããŸããããã§å
±æã³ã³ãã³ããæœåºããæ€èšŒããé©åã«åŠçããŸãã
1. ãµãŒãã¹ã¯ãŒã«ãŒã«ããã€ã³ã¿ãŒã»ãã
å ±æã¿ãŒã²ããããŒã¿ãåŠçããæãä¿¡é Œæ§ã®é«ãæ¹æ³ã¯ããµãŒãã¹ã¯ãŒã«ãŒãä»ããããšã§ãããµãŒãã¹ã¯ãŒã«ãŒã¯ãã¡ã€ã³ã¢ããªã±ãŒã·ã§ã³ã¹ã¬ããããç¬ç«ããŠããã¯ã°ã©ãŠã³ãã§å®è¡ãããå ±æã¿ãŒã²ããã«ãã£ãŠããªã¬ãŒãããPOSTãªã¯ãšã¹ããå«ããããã¯ãŒã¯ãªã¯ãšã¹ããã€ã³ã¿ãŒã»ããã§ããŸããããã«ãããã¢ããªã±ãŒã·ã§ã³ããã©ã¢ã°ã©ãŠã³ãã§ã¢ã¯ãã£ãã«å®è¡ãããŠããªãå Žåã§ããå ±æãªã¯ãšã¹ããåŠçã§ããŸãã
以äžã¯ãå ±æã¿ãŒã²ãããªã¯ãšã¹ããã€ã³ã¿ãŒã»ãããããµãŒãã¹ã¯ãŒã«ãŒã®åºæ¬çãªäŸã§ãã
// service-worker.js
self.addEventListener('fetch', event => {
if (event.request.method === 'POST' && event.request.url.includes('/share-target')) {
event.respondWith(handleShareTarget(event));
}
});
async function handleShareTarget(event) {
const formData = await event.request.formData();
// FormDataãªããžã§ã¯ãããããŒã¿ãæœåº
const title = formData.get('title');
const text = formData.get('text');
const url = formData.get('url');
const files = formData.getAll('sharedFiles');
// å
±æããŒã¿ãåŠç
console.log('Title:', title);
console.log('Text:', text);
console.log('URL:', url);
console.log('Files:', files);
// ãªã¯ãšã¹ãã«å¿çïŒäŸïŒç¢ºèªããŒãžã«ãªãã€ã¬ã¯ãïŒ
return Response.redirect('/confirmation');
}
ãã®ãµãŒãã¹ã¯ãŒã«ãŒã®éèŠãªãã€ã³ãã¯æ¬¡ã®ãšããã§ãã
fetchã€ãã³ããªã¹ããŒ: ããã¯ãã¹ãŠã®ãããã¯ãŒã¯ãªã¯ãšã¹ãããªãã¹ã³ããŸãã- ãªã¯ãšã¹ããã£ã«ã¿ãªã³ã°: ãªã¯ãšã¹ãã
POSTãªã¯ãšã¹ãã§ãããURLã«/share-targetãå«ãŸããŠãããã確èªããŸããããã«ãããå ±æã¿ãŒã²ãããªã¯ãšã¹ãã®ã¿ãã€ã³ã¿ãŒã»ãããããŸãã event.respondWith(): ããã¯ãã©ãŠã¶ãéåžžéããªã¯ãšã¹ããåŠçããã®ãé²ãããµãŒãã¹ã¯ãŒã«ãŒãã«ã¹ã¿ã ã¬ã¹ãã³ã¹ãæäŸã§ããããã«ããŸããhandleShareTarget(): å ±æããŒã¿ãåŠçããéåæé¢æ°ã§ããevent.request.formData(): ããã¯POSTãªã¯ãšã¹ãããã£ãFormDataãªããžã§ã¯ããšããŠè§£æããå ±æããŒã¿ã«ç°¡åã«ã¢ã¯ã»ã¹ã§ããããã«ããŸãã- ããŒã¿æœåº: ã³ãŒãã¯
formData.get()ããã³formData.getAll()ã䜿çšããŠFormDataãªããžã§ã¯ãããã¿ã€ãã«ãããã¹ããURLããã¡ã€ã«ãååŸããŸãã - ããŒã¿åŠç: äŸã®ã³ãŒãã¯ããŒã¿ãã³ã³ãœãŒã«ã«ãã°åºåããã ãã§ããå®éã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãããŒã¿ãããã«åŠçããŸãïŒäŸïŒããŒã¿ããŒã¹ã«ä¿åãããUIã«è¡šç€ºããïŒã
- ã¬ã¹ãã³ã¹: ã³ãŒãã¯ãŠãŒã¶ãŒã確èªããŒãžã«ãªãã€ã¬ã¯ãããããšã§ãªã¯ãšã¹ãã«å¿çããŸããå¿ èŠã«å¿ããŠã¬ã¹ãã³ã¹ãã«ã¹ã¿ãã€ãºã§ããŸãã
éèŠ: ã¡ã€ã³ã®JavaScriptã³ãŒãã§ãµãŒãã¹ã¯ãŒã«ãŒãé©åã«ç»é²ãããŠããããšã確èªããŠãã ãããåçŽãªç»é²ã¹ããããã¯æ¬¡ã®ããã«ãªããŸãã
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(registration => {
console.log('Service Worker registered with scope:', registration.scope);
})
.catch(error => {
console.error('Service Worker registration failed:', error);
});
}
2. ããŒã¿æœåºãšæ€èšŒ
å
±æã¿ãŒã²ãããªã¯ãšã¹ããã€ã³ã¿ãŒã»ããããããæ¬¡ã®ã¹ãããã¯FormDataãªããžã§ã¯ãããããŒã¿ãæœåºããæ€èšŒããããšã§ããããã¯ãããŒã¿ã®æŽåæ§ã確ä¿ããã»ãã¥ãªãã£è匱æ§ãé²ãããã«äžå¯æ¬ ã§ãã
å ±æããŒã¿ãæœåºããŠæ€èšŒããæ¹æ³ã®äŸã以äžã«ç€ºããŸãã
async function handleShareTarget(event) {
const formData = await event.request.formData();
const title = formData.get('title');
const text = formData.get('text');
const url = formData.get('url');
const files = formData.getAll('sharedFiles');
// ããŒã¿ãæ€èšŒ
if (!title) {
console.error('Title is missing.');
return new Response('Title is required.', { status: 400 });
}
if (files && files.length > 0) {
for (const file of files) {
if (file.size > 10 * 1024 * 1024) { // ãã¡ã€ã«ãµã€ãºã10MBã«å¶é
console.error('File size exceeds limit.');
return new Response('File size exceeds limit (10MB).', { status: 400 });
}
if (!file.type.startsWith('image/') && !file.type.startsWith('video/')) {
console.error('Invalid file type.');
return new Response('Invalid file type. Only images and videos are allowed.', { status: 400 });
}
}
}
// å
±æããŒã¿ãåŠçïŒæ€èšŒãæåããå ŽåïŒ
console.log('Title:', title);
console.log('Text:', text);
console.log('URL:', url);
console.log('Files:', files);
// ãªã¯ãšã¹ãã«å¿ç
return Response.redirect('/confirmation');
}
ãã®äŸã¯ã以äžã®æ€èšŒãã§ãã¯ã瀺ããŠããŸãã
- å¿ é ãã£ãŒã«ã: ã¿ã€ãã«ãååšãããã©ããã確èªããŸããååšããªãå Žåã¯ããšã©ãŒã¬ã¹ãã³ã¹ãè¿ããŸãã
- ãã¡ã€ã«ãµã€ãºå¶é: æå€§ãã¡ã€ã«ãµã€ãºã10MBã«å¶éããŸããããã¯ããµãŒãã¹æåŠæ»æãé²ãããµãŒããŒã倧éã®ãã¡ã€ã«ã§éè² è·ã«ãªããªãããã«ããã®ã«åœ¹ç«ã¡ãŸãã
- ãã¡ã€ã«ã¿ã€ãæ€èšŒ: ç»åãã¡ã€ã«ãšãããªãã¡ã€ã«ã®ã¿ãèš±å¯ããŸããããã¯ããŠãŒã¶ãŒãæªæã®ãããã¡ã€ã«ãã¢ããããŒãããã®ãé²ãã®ã«åœ¹ç«ã¡ãŸãã
ãããã®æ€èšŒãã§ãã¯ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ç¹å®ã®èŠä»¶ã«åºã¥ããŠã«ã¹ã¿ãã€ãºããããšãå¿ããªãã§ãã ãããURL圢åŒãããã¹ãé·ãããã³ãã®ä»ã®é¢é£ãã©ã¡ãŒã¿ã®æ€èšŒã远å ããããšãæ€èšããŠãã ããã
3. å ±æãã¡ã€ã«ã®åŠç
å ±æãã¡ã€ã«ãåŠçããå Žåãå¹ççãã€å®å šã«åŠçããããšãéèŠã§ãã以äžã«ããã€ãã®ãã¹ããã©ã¯ãã£ã¹ã瀺ããŸãã
- ãã¡ã€ã«ã³ã³ãã³ãã®èªã¿èŸŒã¿:
FileReaderAPIã䜿çšããŠãå ±æãã¡ã€ã«ã®ã³ã³ãã³ããèªã¿èŸŒã¿ãŸãã - ãã¡ã€ã«ã®å®å šãªä¿å: é©åãªã¢ã¯ã»ã¹å¶åŸ¡ã䜿çšããŠããµãŒããŒäžã®å®å šãªå Žæã«ãã¡ã€ã«ãä¿åããŸããã¹ã±ãŒã©ããªãã£ãšã»ãã¥ãªãã£ã®ããã«ãAmazon S3ãGoogle Cloud StorageãAzure Blob Storageãªã©ã®ã¯ã©ãŠãã¹ãã¬ãŒãžãµãŒãã¹ã®äœ¿çšãæ€èšããŠãã ããã
- äžæã®ãã¡ã€ã«åã®çæ: ååç«¶åãæœåšçãªã»ãã¥ãªãã£è匱æ§ãé²ãããã«ãäžæã®ãã¡ã€ã«åãçæããŸããã¿ã€ã ã¹ã¿ã³ããä¹±æ°ããŠãŒã¶ãŒIDãçµã¿åãããŠäžæã®ãã¡ã€ã«åãçæã§ããŸãã
- ãã¡ã€ã«åã®ãµãã¿ã€ãº: æœåšçã«æªæã®ããæåãåé€ããããã«ãã¡ã€ã«åããµãã¿ã€ãºããŸããããã¯ãã¯ãã¹ãµã€ãã¹ã¯ãªããã£ã³ã°ïŒXSSïŒè匱æ§ãé²ãã®ã«åœ¹ç«ã¡ãŸãã
- ã³ã³ãã³ãã»ãã¥ãªãã£ããªã·ãŒïŒCSPïŒ: ã¢ããªã±ãŒã·ã§ã³ããããŒãã§ãããªãœãŒã¹ã®çš®é¡ãå¶éããããã«ã³ã³ãã³ãã»ãã¥ãªãã£ããªã·ãŒïŒCSPïŒãæ§æããŸããããã«ãããæ»æè ãã¢ããªã±ãŒã·ã§ã³ã«æªæã®ããã³ãŒããæ³šå ¥ããèœåãå¶éããããšã§ãXSSæ»æãé²ãã®ã«åœ¹ç«ã¡ãŸãã
FileReader APIã䜿çšããŠå
±æãã¡ã€ã«ã®ã³ã³ãã³ããèªã¿åãæ¹æ³ã®äŸã以äžã«ç€ºããŸãã
async function processFiles(files) {
for (const file of files) {
const reader = new FileReader();
reader.onload = (event) => {
const fileData = event.target.result;
console.log('File data:', fileData);
// ããã§fileDataãå®å
šã«ã¢ããããŒããŸãã¯ä¿åã§ããŸã
};
reader.onerror = (error) => {
console.error('Error reading file:', error);
};
reader.readAsDataURL(file); // ãã€ããªããŒã¿ã®å Žåã¯readAsArrayBufferã䜿çš
}
}
ãã®ã³ãŒãã¯ãå
±æãã¡ã€ã«ãå埩åŠçããFileReaderã䜿çšããŠåãã¡ã€ã«ã®ããŒã¿ãèªã¿åããŸãããã¡ã€ã«ãæ£åžžã«èªã¿åããããšãã«onloadã€ãã³ããã³ãã©ãåŒã³åºãããfileData倿°ã«ãã¡ã€ã«ã®å
容ãããŒã¿URLïŒãŸãã¯readAsArrayBufferã䜿çšããå Žåã®ArrayBufferïŒãšããŠå«ãŸããŸãããã®åŸããã®ããŒã¿ããµãŒããŒã«ã¢ããããŒãããããããŒã«ã«ããŒã¿ããŒã¹ã«ä¿åãããã§ããŸãã
4. ç°ãªãããŒã¿åã®åŠç
Web Share Target APIã¯ãããã¹ããURLããã¡ã€ã«ãªã©ãããŸããŸãªããŒã¿åãåŠçã§ããŸããå ±æã¿ãŒã²ããããã»ããµã¯ããããã®åããŒã¿åãé©åã«åŠçã§ããå¿ èŠããããŸãã
- ããã¹ã: ããã¹ãããŒã¿ã®å Žåã¯ã
FormDataãªããžã§ã¯ãããããã¹ããæœåºããŠãå¿ èŠã«å¿ããŠåŠçã§ããŸããããšãã°ãããã¹ããããŒã¿ããŒã¹ã«ä¿åããããUIã«è¡šç€ºããããæ€çŽ¢ãå®è¡ããããã«äœ¿çšãããã§ããŸãã - URL: URLã®å Žåã¯ãURL圢åŒãæ€èšŒããå®å šã«ããã²ãŒãã§ããããšã確èªããå¿ èŠããããŸããæ£èŠè¡šçŸãŸãã¯URLè§£æã©ã€ãã©ãªã䜿çšããŠURLãæ€èšŒã§ããŸãã
- ãã¡ã€ã«: åè¿°ã®ããã«ããã¡ã€ã«ã¯ã»ãã¥ãªãã£ã確ä¿ããããŒã¿æå€±ãé²ãããã«æ éãªåŠçãå¿ èŠã§ãããã¡ã€ã«ã¿ã€ããšãµã€ãºãæ€èšŒããã¢ããããŒãããããã¡ã€ã«ãå®å šã«ä¿åããŸãã
5. ãŠãŒã¶ãŒãžã®ãã£ãŒãããã¯ã®è¡šç€º
å ±ææäœã®ã¹ããŒã¿ã¹ã«ã€ããŠãŠãŒã¶ãŒã«ãã£ãŒãããã¯ãæäŸããããšãéèŠã§ããããã¯ãæåã¡ãã»ãŒãžããšã©ãŒã¡ãã»ãŒãžããŸãã¯ããŒãã£ã³ã°ã€ã³ãžã±ãŒã¿ã衚瀺ããããšã§è¡ãããšãã§ããŸãã
- æåã¡ãã»ãŒãž: å ±ææäœãæ£åžžã«å®äºãããšãã«æåã¡ãã»ãŒãžã衚瀺ããŸããããšãã°ããã³ã³ãã³ããæ£åžžã«å ±æãããŸããïŒããšããã¡ãã»ãŒãžã衚瀺ããå ŽåããããŸãã
- ãšã©ãŒã¡ãã»ãŒãž: å ±ææäœã倱æããå Žåã«ãšã©ãŒã¡ãã»ãŒãžã衚瀺ããŸãããŠãŒã¶ãŒãäœãééã£ãŠããã®ãããããŠãããã©ã®ããã«ä¿®æ£ã§ããããçè§£ããã®ã«åœ¹ç«ã€ãæç¢ºã§æ å ±æäŸçãªãšã©ãŒã¡ãã»ãŒãžãæäŸããŸããããšãã°ããã³ã³ãã³ãã®å ±æã«å€±æããŸãããåŸã§ããäžåºŠã詊ããã ãããããšããã¡ãã»ãŒãžã衚瀺ããå ŽåããããŸããå ·äœçãªè©³çްïŒäŸïŒããã¡ã€ã«ãµã€ãºãå¶éãè¶ ããŠããŸãããïŒãå«ããŸãã
- ããŒãã£ã³ã°ã€ã³ãžã±ãŒã¿: å ±ææäœãé²è¡äžã«ããŒãã£ã³ã°ã€ã³ãžã±ãŒã¿ã衚瀺ããŸããããã«ããããŠãŒã¶ãŒã¯ã¢ããªã±ãŒã·ã§ã³ãæ©èœããŠããããšãç¥ããæäœãå®äºãããŸã§ãã以äžã®æäœãè¡ãã®ãé²ãããšãã§ããŸãã
JavaScriptã䜿çšããŠUIãåçã«æŽæ°ãããããã®ã¡ãã»ãŒãžã衚瀺ã§ããŸããéç¥ã©ã€ãã©ãªãŸãã¯ããŒã¹ãã³ã³ããŒãã³ãã䜿çšããŠããŠãŒã¶ãŒã«éäŸµå ¥çãªã¡ãã»ãŒãžã衚瀺ããããšãæ€èšããŠãã ããã
6. ã»ãã¥ãªãã£ã«é¢ããèæ ®äºé
å ±æã¿ãŒã²ããããã»ããµãæ§ç¯ããéã«ã¯ãã»ãã¥ãªãã£ãæåªå äºé ã§ãã以äžã«ããã€ãã®éèŠãªã»ãã¥ãªãã£ã«é¢ããèæ ®äºé ã瀺ããŸãã
- ããŒã¿æ€èšŒ: ãã¹ãŠã®åä¿¡ããŒã¿ãåžžã«æ€èšŒããã€ã³ãžã§ã¯ã·ã§ã³æ»æããã®ä»ã®ã»ãã¥ãªãã£è匱æ§ãé²ããŸããããŒã¿ã®åœ¢åŒãã¿ã€ãããµã€ãºãæ€èšŒããæœåšçã«æªæã®ããæåããµãã¿ã€ãºããŸãã
- ã¯ãã¹ãµã€ãã¹ã¯ãªããã£ã³ã°ïŒXSSïŒ: UIã«è¡šç€ºããããŠãŒã¶ãŒæäŸã®ããŒã¿ã¯ãã¹ãŠãšã¹ã±ãŒãããããšã§ãXSSæ»æããä¿è·ããŸããHTMLãšã³ãã£ãã£ãèªåçã«ãšã¹ã±ãŒããããã³ãã¬ãŒããšã³ãžã³ã䜿çšããããå°çšã®XSSä¿è·ã©ã€ãã©ãªã䜿çšããŸãã
- ã¯ãã¹ãµã€ããªã¯ãšã¹ããã©ãŒãžã§ãªïŒCSRFïŒ: CSRFããŒã¯ã³ã䜿çšããŠãCSRFæ»æããä¿è·ããŸããCSRFããŒã¯ã³ã¯ããµãŒããŒã«ãã£ãŠçæããããã¹ãŠã®ãã©ãŒã ãšAJAXãªã¯ãšã¹ãã«å«ãŸããããŠããŒã¯ã§äºæž¬äžå¯èœãªå€ã§ããããã«ãããæ»æè ãèªèšŒæžã¿ãŠãŒã¶ãŒã®ä»£ããã«ãªã¯ãšã¹ããåœé ããã®ãé²ããŸãã
- ãã¡ã€ã«ã¢ããããŒãã»ãã¥ãªãã£: ãŠãŒã¶ãŒãæªæã®ãããã¡ã€ã«ãã¢ããããŒãããã®ãé²ãããã«ãå ç¢ãªãã¡ã€ã«ã¢ããããŒãã»ãã¥ãªãã£å¯Ÿçãå®è£ ããŸãããã¡ã€ã«ã¿ã€ãããã¡ã€ã«ãµã€ãºããã¡ã€ã«ã³ã³ãã³ããæ€èšŒããã¢ããããŒãããããã¡ã€ã«ãé©åãªã¢ã¯ã»ã¹å¶åŸ¡ãšãšãã«å®å šãªå Žæã«ä¿åããŸãã
- HTTPS: ã¢ããªã±ãŒã·ã§ã³ãšãµãŒããŒéã®ãã¹ãŠã®éä¿¡ãæå·åããããã«ãåžžã«HTTPSã䜿çšããŸããããã«ãããæ»æè ãæ©å¯ããŒã¿ãçèŽããã®ãé²ããŸãã
- ã³ã³ãã³ãã»ãã¥ãªãã£ããªã·ãŒïŒCSPïŒ: ã¢ããªã±ãŒã·ã§ã³ããããŒãã§ãããªãœãŒã¹ã®çš®é¡ãå¶éããããã«CSPãæ§æããŸããããã«ãããæ»æè ãã¢ããªã±ãŒã·ã§ã³ã«æªæã®ããã³ãŒããæ³šå ¥ããèœåãå¶éããããšã§ãXSSæ»æãé²ãã®ã«åœ¹ç«ã¡ãŸãã
- 宿çãªã»ãã¥ãªãã£ç£æ»: 宿çãªã»ãã¥ãªãã£ç£æ»ã宿œããŠãæœåšçãªã»ãã¥ãªãã£è匱æ§ãç¹å®ããä¿®æ£ããŸããèªååãããã»ãã¥ãªãã£ã¹ãã£ã³ããŒã«ã䜿çšããã»ãã¥ãªãã£å°éå®¶ãšååããŠãã¢ããªã±ãŒã·ã§ã³ãå®å šã§ããããšã確èªããŸãã
äŸãšãŠãŒã¹ã±ãŒã¹
以äžã¯ãå®éã®ã¢ããªã±ãŒã·ã§ã³ã§Web Share Target APIã䜿çšããæ¹æ³ã®äŸã§ãã
- ãœãŒã·ã£ã«ã¡ãã£ã¢ã¢ããª: ãŠãŒã¶ãŒãä»ã®ã¢ããªããã³ã³ãã³ããçŽæ¥ãœãŒã·ã£ã«ã¡ãã£ã¢ãã©ãããã©ãŒã ã«å ±æã§ããããã«ããŸããããšãã°ããŠãŒã¶ãŒã¯ãã¥ãŒã¹ã¢ããªããããªãã®ãœãŒã·ã£ã«ã¡ãã£ã¢ã¢ããªã«ãäºåã«äœæãããã¡ãã»ãŒãžãšãšãã«ãªã³ã¯ãå ±æã§ããŸãã
- ã¡ã¢åãã¢ããª: ãŠãŒã¶ãŒãä»ã®ã¢ããªããããã¹ããURLããã¡ã€ã«ãçŽæ¥ã¡ã¢åãã¢ããªã«å ±æã§ããããã«ããŸããããšãã°ããŠãŒã¶ãŒã¯ã³ãŒããšãã£ã¿ããããªãã®ã¡ã¢åãã¢ããªã«ã³ãŒãã¹ãããããå ±æã§ããŸãã
- ç»åç·šéã¢ããª: ãŠãŒã¶ãŒãä»ã®ã¢ããªããç»åãçŽæ¥ç»åç·šéã¢ããªã«å ±æã§ããããã«ããŸããããšãã°ããŠãŒã¶ãŒã¯ãã©ãã®ã£ã©ãªãŒã¢ããªããããªãã®ç»åç·šéã¢ããªã«åçãå ±æã§ããŸãã
- Eã³ããŒã¹ã¢ããª: ãŠãŒã¶ãŒãä»ã®ã¢ããªããååãçŽæ¥Eã³ããŒã¹ã¢ããªã«å ±æã§ããããã«ããŸããããšãã°ããŠãŒã¶ãŒã¯ã·ã§ããã³ã°ã¢ããªããããªãã®Eã³ããŒã¹ã¢ããªã«ååãå ±æããŠäŸ¡æ Œãæ¯èŒã§ããŸãã
- ã³ã©ãã¬ãŒã·ã§ã³ããŒã«: ãŠãŒã¶ãŒãä»ã®ã¢ããªããããã¥ã¡ã³ãããã¡ã€ã«ãçŽæ¥ã³ã©ãã¬ãŒã·ã§ã³ããŒã«ã«å ±æã§ããããã«ããŸããããšãã°ããŠãŒã¶ãŒã¯ããã¥ã¡ã³ããšãã£ã¿ã¢ããªããããªãã®ã³ã©ãã¬ãŒã·ã§ã³ããŒã«ã«ããã¥ã¡ã³ããå ±æããŠã¬ãã¥ãŒã§ããŸãã
åºæ¬ãè¶ ããŠ: é«åºŠãªãã¯ããã¯
åºæ¬çãªå ±æã¿ãŒã²ããããã»ããµãã»ããã¢ãããããããã®æ©èœã匷åããããã«ããã€ãã®é«åºŠãªãã¯ããã¯ãæ€èšã§ããŸãã
- ã«ã¹ã¿ã å ±æã·ãŒã: æšæºã®å ±æã·ãŒãã¯ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ãã£ãŠæäŸãããŸããããããã«ã¹ã¿ã èŠçŽ ã䜿çšããŠå ±æã·ãŒããšã¯ã¹ããªãšã³ã¹ã«åœ±é¿ãäžããããè£åŒ·ãããã§ããå¯èœæ§ããããŸãããããã¯ãã©ãããã©ãŒã ãšãã®å ±ææ©èœã«å€§ããäŸåããŸãããã©ãããã©ãŒã ã®å¶éã«ãããã«ã¹ã¿ãã€ãºã®åºŠåããå¶éãããå¯èœæ§ãããããšã«æ³šæããŠãã ããã
- ããã°ã¬ãã·ããšã³ãã³ã¹ã¡ã³ã: å ±æã¿ãŒã²ããæ©èœãããã°ã¬ãã·ããšã³ãã³ã¹ã¡ã³ããšããŠå®è£ ããŸããWeb Share Target APIããã©ãŠã¶ã§ãµããŒããããŠããªãå Žåã§ããã¢ããªã±ãŒã·ã§ã³ã¯å ±æã¿ãŒã²ããæ©èœãªãã§ãæ£ããæ©èœããŸãã
- é å»¶åŠç: è€éãªåŠçã¿ã¹ã¯ã®å Žåã¯ãåŠçãããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ã«é å»¶ãããããšãæ€èšããŠãã ãããããã«ãããã¢ããªã±ãŒã·ã§ã³ã®å¿çæ§ãåäžããUIãããªãŒãºããã®ãé²ãããšãã§ããŸãããããã®ã¿ã¹ã¯ã管çããããã«ãããã¯ã°ã©ãŠã³ããã¥ãŒãŸãã¯å°çšã®ããã¯ã°ã©ãŠã³ãåŠçã©ã€ãã©ãªã䜿çšã§ããŸãã
- åæãšç£èŠ: å ±æã¿ãŒã²ããæ©èœã®äœ¿çšç¶æ³ã远跡ããŠããŠãŒã¶ãŒãã©ã®ããã«ã³ã³ãã³ããã¢ããªã±ãŒã·ã§ã³ã«å ±æããŠãããã«ã€ããŠã®æŽå¯ãåŸãŸããããã«ãããæ¹åç¹ãç¹å®ããå ±æã¿ãŒã²ãããšã¯ã¹ããªãšã³ã¹ãæé©åã§ããŸãã
ã¯ãã¹ãã©ãããã©ãŒã ã®èæ ®äºé
Web Share Target APIã¯ã¯ãã¹ãã©ãããã©ãŒã åãã«èšèšãããŠããŸãããçæãã¹ããã©ãããã©ãŒã åºæã®èæ ®äºé ãããå ŽåããããŸãã
- Android: Androidã§ã¯ãå ±æã·ãŒãã¯é«åºŠã«ã«ã¹ã¿ãã€ãºå¯èœã§ãããããªãã®ã¢ããªã±ãŒã·ã§ã³ã¯ãŠãŒã¶ãŒã®èšå®ã«ãã£ãŠå ±æã·ãŒãã®ç°ãªãäœçœ®ã«è¡šç€ºãããå¯èœæ§ããããŸãã
- iOS: iOSã§ã¯ãå ±æã·ãŒãã¯ã«ã¹ã¿ãã€ãºæ§ãäœãããŠãŒã¶ãŒãæè¿äœ¿çšããŠããªãå Žåãããªãã®ã¢ããªã±ãŒã·ã§ã³ãå ±æã·ãŒãã«åžžã«è¡šç€ºããããšã¯éããŸããã
- ãã¹ã¯ããã: ãã¹ã¯ããããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§ã¯ãå ±æã·ãŒããç°ãªãå ŽåãããŸã£ããå©çšã§ããªãå ŽåããããŸãã
ããŸããŸãªãã©ãããã©ãŒã ã§å ±æã¿ãŒã²ããæ©èœããã¹ãããŠãæ£ããæ©èœããäžè²«ãããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæäŸããŠããããšã確èªããŠãã ããã
çµè«
å ç¢ã§å®å šãªããã³ããšã³ãå ±æã¿ãŒã²ããããã»ããµãæ§ç¯ããããšã¯ãWeb Share Target APIã®åãæŽ»çšããããã«äžå¯æ¬ ã§ãããã®ã¬ã€ãã§æŠèª¬ããããã¹ããã©ã¯ãã£ã¹ã«åŸãããšã§ããŠã§ãã¢ããªã±ãŒã·ã§ã³ãžã®ã³ã³ãã³ãå ±æã®ããã®ã·ãŒã ã¬ã¹ã§é åçãªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãäœæã§ããŸããã»ãã¥ãªãã£ãåªå ãããã¹ãŠã®åä¿¡ããŒã¿ãæ€èšŒãããŠãŒã¶ãŒã«æç¢ºãªãã£ãŒãããã¯ãæäŸããããšãå¿ããªãã§ãã ãããWeb Share Target APIã¯ãæ£ããå®è£ ãããŠããã°ãPWAãšãŠãŒã¶ãŒã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãšã®çµ±åãå€§å¹ ã«åŒ·åããå šäœçãªäœ¿ãããããåäžãããããšãã§ããŸãã